package com.hb.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;

import java.nio.charset.StandardCharsets;

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
    /**
     * 配置静态资源的处理
     * 我们要求 DispatcherServlet 将对静态资源的请求转发到 Servlet 容器中默认的 Servlet 上，而不是使用 DispatcherServlet 本身来处理此类请求。
     * @param configurer
     */
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        // 通过启用默认 Servlet 处理配置后 DispatcherServlet 将对静态资源的请求转发到 Servlet 容器中默认的 Servlet 上，而不是使用 DispatcherServlet 本身来处理此类请求
        configurer.enable();
    }

    /**
     * 加载 Thymeleaf 模板
     * TemplateResolver 会最终定位和查找模板。与之前配置 InternalResourceViewResolver类似，它使用了 prefix 和 suffix 属性。
     * 前缀和后缀将会与逻辑视图名组合使用，进而定位 Thymeleaf 引擎。它的 templateMode 属性被设置成了 HTML 5，这表明我们预期要解析的模板会渲染成 HTML 5 输出。
     * @return
     */
    @Bean
    public TemplateResolver templateResolver() {
        TemplateResolver templateResolver = new ServletContextTemplateResolver();
        templateResolver.setPrefix("/WEB-INF/views/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode("HTML5");
        templateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
        return templateResolver;
    }

    /**
     * Spring 模板引擎：处理模板并渲染结果
     * SpringTemplateEngine 会在 Spring 中启用 Thymeleaf 引擎，用来解析模板，并基于这些模板渲染结果。
     * @param templateResolver
     * @return
     */
    @Bean
    public SpringTemplateEngine templateEngine(TemplateResolver templateResolver) {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver);
        // 注册安全方言
        templateEngine.addDialect(new SpringSecurityDialect());
        return templateEngine;
    }

    /**
     * Thymeleaf 视图解析器
     * 1、ThymeleafViewResolver 是 Spring MVC 中 ViewResolver 的一个实现类。像其他的视图解析器一样，它会接受一个逻辑视图名称，并将其解析为视图。
     * 不过在该场景下，视图会是一个 Thymeleaf 模板。
     * 2、需要注意的是 ThymeleafViewResolver bean 中注入了一个对 SpringTemplateEngine bean 的引用。SpringTemplateEngine 会在 Spring 中启用 Thymeleaf 引擎，
     * 用来解析模板，并基于这些模板渲染结果。
     * 3、另外我们又为 SpringTemplateEngine 注入了一个 TemplateResolver bean 的引用。TemplateResolver 会最终定位和查找模板。
     * 与之前配置 InternalResourceViewResolver类似，它使用了 prefix 和 suffix 属性。前缀和后缀将会与逻辑视图名组合使用，进而定位 Thymeleaf 引擎。
     * 它的 templateMode 属性被设置成了 HTML 5，这表明我们预期要解析的模板会渲染成 HTML 5 输出。
     * @param templateEngine
     * @return
     */
    @Bean
    public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine);
        viewResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
        return viewResolver;
    }
}
